package com.upb.webserver.fisco.data;

import com.upb.webserver.account.AccountService;
import com.upb.webserver.common.pojo.account.AccountCommon;
import com.upb.webserver.common.pojo.base.BasePageResponse;
import com.upb.webserver.common.pojo.base.BaseResponse;
import com.upb.webserver.common.pojo.rest.fisco.data.req.EventExportInfo;
import com.upb.webserver.common.pojo.rest.fisco.data.req.EventExportUpdateParam;
import com.upb.webserver.common.pojo.rest.fisco.data.req.EventInfoParam;
import com.upb.webserver.common.pojo.rest.fisco.data.req.NormalSearchParamForFisco;
import com.upb.webserver.rest.fisco.FiscoChainMgrRestService;
import com.upb.webserver.rest.fisco.FiscoDataFetchRestService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.math.BigInteger;

/**
 * request data from webase-data-fetcher.
 */
@Log4j2
@RestController
@RequestMapping(value = "fisco-fetcher")
public class FiscoDataFetchController {

    @Autowired
    private FiscoDataFetchRestService fiscoDataFetchRestService;
    @Autowired
    private FiscoChainMgrRestService fiscoChainMgrRestService;

    /**
     * get data overview.
     */
    @GetMapping("chain/general")
    public BaseResponse getDataGeneral() {
        log.info("fisco-fetcher getDataGeneral.");
        return fiscoDataFetchRestService.getDataGeneral();
    }

    /**
     * get chain list.
     */
    @GetMapping("chain/all")
    public BasePageResponse getChainList() {
        log.info("fisco-fetcher getChainList.");
        return fiscoDataFetchRestService.getChainList();
    }

    /**
     * get group list by chainId.
     *
     * @param chainId
     * @return
     */
    @GetMapping("group/list")
    public BasePageResponse getGroupList(@RequestParam(value = "chainId", required = false) Integer chainId) {
        log.info("fisco-fetcher getGroupList.");
        return fiscoDataFetchRestService.getGroupList(chainId);
    }

    /**
     * get group info.
     *
     * @param chainId
     * @param groupId
     * @return
     */
    @GetMapping("group/general/{chainId}/{groupId}")
    public BaseResponse getGroupGeneral(@PathVariable("chainId") Integer chainId,
                                        @PathVariable("groupId") Integer groupId) {
        log.info("fisco-fetcher getGroupGeneral.");
        return fiscoDataFetchRestService.getGroupGeneral(chainId, groupId);
    }

    /**
     * get transaction daily data.
     *
     * @param chainId
     * @param groupId
     * @return
     */
    @GetMapping("group/txnDaily/{chainId}/{groupId}")
    public BaseResponse getTransDaily(@PathVariable("chainId") Integer chainId,
                                      @PathVariable("groupId") Integer groupId) {
        log.info("fisco-fetcher getTransDaily.");
        return fiscoDataFetchRestService.getTransDaily(chainId, groupId);
    }

    /**
     * get node list.
     *
     * @param chainId
     * @param groupId
     * @param pageNumber
     * @param pageSize
     * @return
     */
    @GetMapping("group/nodeList/{chainId}/{groupId}/{pageNumber}/{pageSize}")
    public BasePageResponse getNodeList(@PathVariable("chainId") Integer chainId,
                                        @PathVariable("groupId") Integer groupId, @PathVariable("pageNumber") Integer pageNumber,
                                        @PathVariable("pageSize") Integer pageSize) {
        log.info("fisco-fetcher getNodeList.");

        // TODO 临时方案，最终方案待讨论，目的：刷新chain-manager保存的节点状态
        fiscoChainMgrRestService.selectNodeInfoList(chainId, groupId);
        return fiscoDataFetchRestService.getNodeList(chainId, groupId, pageNumber, pageSize);
    }

    /**
     * get block list.
     *
     * @param chainId
     * @param groupId
     * @param pageNumber
     * @param pageSize
     * @param blockHash
     * @param blockNumber
     * @return
     */
    @GetMapping("group/blockList/{chainId}/{groupId}/{pageNumber}/{pageSize}")
    public BasePageResponse getBlockList(@PathVariable("chainId") Integer chainId,
                                         @PathVariable("groupId") Integer groupId, @PathVariable("pageNumber") Integer pageNumber,
                                         @PathVariable("pageSize") Integer pageSize,
                                         @RequestParam(value = "blockHash", required = false) String blockHash,
                                         @RequestParam(value = "blockNumber", required = false) BigInteger blockNumber) {
        log.info("fisco-fetcher getBlockList.");
        return fiscoDataFetchRestService.getBlockList(chainId, groupId, pageNumber, pageSize, blockHash, blockNumber);
    }

    /**
     * get transaction list.
     *
     * @param chainId
     * @param groupId
     * @param pageNumber
     * @param pageSize
     * @param transHash
     * @param blockNumber
     * @return
     */
    @GetMapping("group/transList/{chainId}/{groupId}/{pageNumber}/{pageSize}")
    public BasePageResponse getTransList(@PathVariable("chainId") Integer chainId,
                                         @PathVariable("groupId") Integer groupId, @PathVariable("pageNumber") Integer pageNumber,
                                         @PathVariable("pageSize") Integer pageSize,
                                         @RequestParam(value = "transHash", required = false) String transHash,
                                         @RequestParam(value = "blockNumber", required = false) BigInteger blockNumber, HttpServletRequest request) {
        log.info("fisco-fetcher getTransList.");
        AccountCommon accountCommon = accountService.getAccountCommon(request);
        return fiscoDataFetchRestService.getTransList(chainId, groupId, pageNumber, pageSize, transHash, blockNumber, accountCommon);
    }

    /**
     * get user list.
     *
     * @param chainId
     * @param groupId
     * @param pageNumber
     * @param pageSize
     * @param userParam(user name or address)
     * @return
     */
    @GetMapping("group/userList/{chainId}/{groupId}/{pageNumber}/{pageSize}")
    public BasePageResponse getUserList(@PathVariable("chainId") Integer chainId,
                                        @PathVariable("groupId") Integer groupId, @PathVariable("pageNumber") Integer pageNumber,
                                        @PathVariable("pageSize") Integer pageSize,
                                        @RequestParam(value = "userParam", required = false) String userParam) {
        log.info("fisco-fetcher getUserList.");
        return fiscoDataFetchRestService.getUserList(chainId, groupId, pageNumber, pageSize, userParam);
    }

    /**
     * get contract list.
     *
     * @param chainId
     * @param groupId
     * @param pageNumber
     * @param pageSize
     * @param contractParam(contract name or address)
     * @return
     */
    @GetMapping("group/contractList/{chainId}/{groupId}/{pageNumber}/{pageSize}")
    public BasePageResponse getContractList(@PathVariable("chainId") Integer chainId,
                                            @PathVariable("groupId") Integer groupId, @PathVariable("pageNumber") Integer pageNumber,
                                            @PathVariable("pageSize") Integer pageSize,
                                            @RequestParam(value = "contractParam", required = false) String contractParam) {
        log.info("fisco-fetcher getContractList.");
        return fiscoDataFetchRestService.getContractList(chainId, groupId, pageNumber, pageSize, contractParam);
    }

    @Autowired
    private AccountService accountService;

    /**
     * search data by condition.
     *
     * @param queryParam(search condition)
     * @return
     */
    @PostMapping("search/normal")
    public BasePageResponse searchMormalList(@RequestBody NormalSearchParamForFisco queryParam, HttpServletRequest request) {
        log.info("fisco-fetcher searchMormalList.");
        AccountCommon accountCommon = accountService.getAccountCommon(request);
        return fiscoDataFetchRestService.searchMormalList(queryParam, accountCommon);
    }

    /**
     * search receipt by condition
     * @param queryParam
     * @return
     */
    @PostMapping("search/receipt")
    public BasePageResponse searchReceiptList(@RequestBody NormalSearchParamForFisco queryParam){
        log.info("fisco-fetcher searchReceiptList.");
        return fiscoDataFetchRestService.searchReceiptList(queryParam);
    }

    /**
     * search data by keyword.
     *
     * @param pageNumber
     * @param pageSize
     * @param keyword
     * @return
     */
    @GetMapping("search/keyword/{pageNumber}/{pageSize}")
    public BasePageResponse searchByKeyword(@PathVariable("pageNumber") Integer pageNumber,
                                            @PathVariable("pageSize") Integer pageSize,
                                            @RequestParam(value = "keyword", required = true) String keyword) {
        log.info("fisco-fetcher searchByKeyword.");
        return fiscoDataFetchRestService.searchByKeyword(pageNumber, pageSize, keyword);
    }

    /**
     * add event export info.
     *
     * @param eventExportInfo
     * @return
     */
    @PostMapping("event/export/add")
    public BaseResponse newEventExportInfo(@RequestBody @Valid EventExportInfo eventExportInfo, BindingResult result) {
        log.info("fisco-fetcher newEventExportInfo.");
        return fiscoDataFetchRestService.newEventExportInfo(eventExportInfo);
    }

    /**
     * get event export info list.
     *
     * @param chainId
     * @param groupId
     * @param pageNumber
     * @param pageSize
     * @param contractAddress
     * @return
     */
    @GetMapping("event/export/list/{chainId}/{groupId}/{pageNumber}/{pageSize}")
    public BasePageResponse getEventExportInfoList(@PathVariable("chainId") Integer chainId,
                                                   @PathVariable("groupId") Integer groupId, @PathVariable("pageNumber") Integer pageNumber,
                                                   @PathVariable("pageSize") Integer pageSize,
                                                   @RequestParam(value = "contractAddress", required = false) String contractAddress) {
        log.info("fisco-fetcher getEventExportInfoList.");
        return fiscoDataFetchRestService.getEventExportInfoList(pageNumber, pageSize, chainId, groupId,
                contractAddress);
    }

    /**
     * update event export info.
     */

    @PostMapping("event/export/updateStatus")
    public BaseResponse updateExportStatus(@RequestBody @Valid EventExportUpdateParam param, BindingResult result) {
        log.info("fisco-fetcher updateExportStatus.");
        return fiscoDataFetchRestService.updateExportStatus(param);
    }

    /**
     * delete audit info by id.
     *
     * @param id
     * @return
     */
    @GetMapping("event/export/deleteById/{id}")
    public BaseResponse removeEventExportInfo(@PathVariable("id") Integer id) {
        log.info("fisco-fetcher removeEventExportInfo.");
        return fiscoDataFetchRestService.removeEventExportInfo(id);
    }

    /**
     * get event info list.
     *
     * @return
     */
    @PostMapping("event/info/list")
    public BasePageResponse getEvenInfoList(@RequestBody @Valid EventInfoParam eventInfoParam, BindingResult result) {
        log.info("fisco-fetcher getEvenInfoList.");
        return fiscoDataFetchRestService.getEvenInfoList(eventInfoParam);
    }

}
